declare var require: any 

import { HttpClient } from '@angular/common/http';
import { Component, EventEmitter, Inject, Input, OnInit, Output, ViewChild } from '@angular/core';
import { FormArray, FormBuilder, FormGroup } from '@angular/forms';
import { MatDialog} from '@angular/material/dialog';
import { ActivatedRoute, Router } from '@angular/router';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { EditSettingsModel, GridComponent, ToolbarItems, ForeignKeyService, EditService, ToolbarService, IEditCell, RowSelectEventArgs, SaveEventArgs, RowDataBoundEventArgs} from '@syncfusion/ej2-angular-grids';
import { Subscription } from 'rxjs';
import { VesselChooseFormComponent } from 'src/app/components/vessel-choose-form/vessel-choose-form.component';
import { TokenStorageService } from 'src/app/services/security/token-storage.service';
import { isAppIdentity } from '../../oc-core/app-defs/app-identity';
import { BaseDialogComponent } from '../../oc-core/components/base-dialog/base-dialog.component';
import { ConfirmDialogComponent } from '../../oc-core/components/confirm-dialog/confirm-dialog.component';
import { DialogChildItem } from '../../oc-core/models/dialog-child-item.model';
import { CrudGenericService } from '../../oc-core/services/crud-generic.service';
import { GlobalService } from '../../oc-core/services/global.service';
import { ChargeCodesModel } from '../models/charge-codes.model';
import { VesselModel } from '../models/vessel.model';
import { VoyageCallsModel } from '../models/voyage-calls.model';
import { VoyageCargoModel } from '../models/voyage-cargo.model';
import { VoyageOperatorChargeModel } from '../models/voyage-operator-charge.model';
import { VoyageOperatorContractModel } from '../models/voyage-operator-contract.model';
import { VoyageOverviewModel } from '../models/voyage-overview.model';
import { VoyageStatusModel } from '../models/voyage-status.model';
import { DatePicker } from '@syncfusion/ej2-calendars'
import { VoyageOperationsFormComponent } from '../voyage-operations-form/voyage-operations-form.component';
import { PortChooseFormComponent } from 'src/app/components/port-choose-form/port-choose-form.component';
import { CustomerShipperChargeModel } from '../models/customer-shipper-charge.model';
import { ContractFormComponent } from '../contract-form/contract-form.component';
import { DropDownList } from '@syncfusion/ej2-dropdowns';
import { SetCargoTypeModel } from '../models/set-cargo-type.model';
import { ShipperChooseFormComponent } from '../shipper-choose-form/shipper-choose-form.component';
import { ChargeListPickerComponent } from '../charge-list-picker/charge-list-picker.component';
import { loadCldr, setCulture} from '@syncfusion/ej2-base'; 
import { ShippmentListComponent } from '../shippment-list/shippment-list.component';
import { ShippmentModule } from '../shippment.module';
import { ConfirmationDialogComponent } from '../../oc-core/components/confirmation-dialog/confirmation-dialog.component';
import { getMatFormFieldPlaceholderConflictError } from '@angular/material';

@Component({
  selector: 'app-shippment-form',
  templateUrl: './shippment-form.component.html',
  styleUrls: ['./shippment-form.component.css'],
  providers:[ForeignKeyService, EditService, ToolbarService]
})

export class ShippmentFormComponent implements OnInit {

  private subscription: Subscription = new Subscription();
  ShippmentFormGroup: FormGroup;

  @ViewChild('gridCalls', {static: false}) public gridCalls: GridComponent;
  @ViewChild('gridCharges', {static: false}) public gridCharges: GridComponent;
  @ViewChild('gridContract', {static: false}) public gridContract: GridComponent;

  public editSettings: EditSettingsModel;
  public toolbar: ToolbarItems[];

  public userId: number;

  public isEdit: boolean;

  cargoModel: VoyageCargoModel[] = [];
  callsArray: VoyageCallsModel[] = [];

  callsArrayPreliminary: VoyageCallsModel[] = [];
  callsArrayFinal: VoyageCallsModel[] = [];

  contractArray: VoyageOperatorContractModel[];
  chargeArray: VoyageOperatorChargeModel[];
  voyageTypeArray: VoyageStatusModel[];
  chargesArray: ChargeCodesModel[];
  customerShipperArray: CustomerShipperChargeModel[];
  setCargoTypeArray: SetCargoTypeModel[];
  portsArray: Object[];

  statusList = [{ state: 'CONFIRMED', name: 'Voyage Confirmed' }, { state: 'OPEN', name: 'Voyage Opened' }];
  marketList = [{ state: 'ME', name: 'Middle East' }, { state: 'NA', name: 'North Africa' }, { state: 'OR', name: 'Other' }];
  cargoList = [];
  voyageTypeList = [];
  customerShipper :  { [key: string]: Object }[] = [];
  serviceOperationCodeArray: Object[] = [{'operation': 'Loading'}, {'operation': 'Discharging'}, {'operation': 'Balast'}, {'operation': 'Bunkering'}, {'operation': 'Other'}];
  chargeItemStatus: { [key: string]: Object }[] = [{'status': 'CONFIRMED', 'value': 1}, {'status': 'RESERVED', 'value': 0}];
  currencyArray: { [key: string]: Object }[] = [{'currency': 'EUR'}, {'currency': 'USD'}, {'currency': 'KN'}];
  chargeTypeArray: { [key: string]: Object }[] = [{'type': 'Debit', 'value': 1}, {'type': 'Credit', 'value': 0}];
  chargeObj: { [key: string]: Object }[] = [];
  setCargoTypeList: { [key: string]: Object }[] = [];
  
  vesselName: String = null;
  vesselCode: String =  null;
  vesselSpeed: Number = null;
  vesselId: Number = null;
  voyageCompute: string;
  public dpParams: IEditCell;
  public customAttributes: Object;

  public etaParam: IEditCell;
  public etdParam: IEditCell;

  public etaElem: HTMLElement;
  public etaObj: DatePicker;

  public etdElem: HTMLElement;
  public etdObj: DatePicker;

  public chargePickElem : HTMLElement;
  public chargePickObj : DropDownList;

  public accountCustomerElem : HTMLElement;
  public accountCustomerObj : DropDownList;

  public setCargoTypeElem : HTMLElement;
  public setCargoTypeObj : DropDownList;

  public currencyElem: HTMLElement;
  public currencyObj: DropDownList;

  public debitCreditElem: HTMLElement;
  public debitCreditObj: DropDownList;

  public chargePickParams: IEditCell;
  public accountCustomerParams: IEditCell;
  public setCargoTypeEdit: IEditCell;
  public currencyParams: IEditCell;
  public debitCreditParams: IEditCell;

  @Input() input: any;
  @Output() output = new EventEmitter<any>();

  parentList: VoyageOverviewModel[];

  public selectedRowCalls: object;
  public selectedCallIndex: number[];

  public selectedRowCharge: object;
  public selectedChargeIndex: number[];

  public selectedRowContract: object;
  public selectedContractIndex: number[];

  public isDataChanged: boolean = false;
  public retireveAfterClose: boolean = false;

  public indexArray: Array<number> = [];

  initialChargeDesc = "";
  initialAccountCustomer = "";
  initialCargoType = "";
  initialCurrency = "";
  initialDebitCredit: number;
  initialShipper = "";

  customerReceiverChanged: boolean = false;
  customerReceivedChangedSynonim: string = '';

  portNameChanged: boolean = false;
  portNameChangedName: string = '';

  callStatusArray = ['PRELIMINARY', 'FINAL'];

  initialForm: FormGroup;

  public volumeAmountFormatter = (field: number, data1: object, column: object) => {
    let volumeAmount = Number(data1['volumeAmount']).toLocaleString('de-DE', {maximumFractionDigits: 0}) + ' m3';
    return volumeAmount;
  }

  public weightAmountFormatter = (field: number, data1: object, column: object) => {
    let weightAmount = Number(data1['weightAmount']).toLocaleString('de-DE', {maximumFractionDigits: 0}) + ' mt';
    return weightAmount;
  }

  public lumpsumFormatter = (field: number, data1: object, column: object) => {
    let lumpsumAmount;
    switch(data1['currencyCode']){
      case 'EUR':
        lumpsumAmount = Number(data1['lumpsumAmount']).toLocaleString('de-DE', {minimumFractionDigits: 2}) + ' €';
        break;
      case 'KN':
        lumpsumAmount = Number(data1['lumpsumAmount']).toLocaleString('de-DE', {minimumFractionDigits: 2}) + ' KN';
        break;
      case 'USD':
        lumpsumAmount = Number(data1['lumpsumAmount']).toLocaleString('de-DE', {minimumFractionDigits: 2}) + ' $';
        break;
    }
    return lumpsumAmount;
  }

  constructor(private globalService: GlobalService, private fb: FormBuilder, private crudService: CrudGenericService,
    private httpClient: HttpClient, public dialog: MatDialog, private modalService: NgbModal, private router: Router, private route: ActivatedRoute, 
    private tokenStorageService: TokenStorageService) {
     }

  ngOnInit() {

    setCulture('en'); 
    loadCldr(require('../../format_json/numbers.json'), require('../../format_json/ca-gregorian.json'), require('../../format_json/timeZoneNames.json')); 

    let voyageCargo: VoyageCargoModel;
    let voyageCalls: VoyageCallsModel;
    let voyageOperatorContract: VoyageOperatorContractModel;
    let voyageStatus: VoyageStatusModel;
    let chargesModel: ChargeCodesModel;
    let customerShipper: CustomerShipperChargeModel;
    let setCargoType: SetCargoTypeModel;
    this.dpParams = { params: {value: new Date() } };

    this.editSettings = { allowEditing: true, mode: 'Normal'};
    this.customAttributes = {class: 'customcss'};

    this.userId = this.tokenStorageService.getUser().id;
    
    this.etaParam = {
      create: () => {
        this.etaElem = document.createElement('input');
        return this.etaElem;
      },
      read: () => {
        return this.etaObj.value;
    },
      destroy: () => {
        this.etaObj.destroy();
      },
      write: args => {
        var rowData = args.rowData;
        var rowIndex = this.gridCalls.getRowInfo(args.row).rowIndex;
        this.etaObj = new DatePicker({
          value: new Date (args.rowData[args.column.field]),
          floatLabelType: 'Never', 
          change: function(args){
            let daysDiff = (this.etdObj.value.getTime() - args.value.getTime())/1000/60/60/24;
            var formEle = document.getElementById("gridCalls").querySelector("form").ej2_instances[0];
            var portDays = formEle.getInputElement('portDays');
            portDays.value = daysDiff;
          }.bind(this)
        });
        this.etaObj.appendTo(this.etaElem);
      }
    };

    this.etdParam = {
      create: () => {
        this.etdElem = document.createElement('input');
        return this.etdElem;
      },
      read: () => {
        return this.etdObj.value;
    },
      destroy: () => {
        this.etdObj.destroy();
      },
      write: args => {
        var rowData = args.rowData;
        var rowIndex = this.gridCalls.getRowInfo(args.row).rowIndex;
        this.etdObj = new DatePicker({
          value: new Date (args.rowData[args.column.field]),
          floatLabelType: 'Never', 
          change: function(args){
            let daysDiff = (args.value.getTime() - this.etaObj.value.getTime())/1000/60/60/24;
            var formEle = document.getElementById("gridCalls").querySelector("form").ej2_instances[0];
            var portDays = formEle.getInputElement('portDays');
            portDays.value = daysDiff;
          }.bind(this)
        });
        this.etdObj.appendTo(this.etdElem);
      }
    };

    this.crudService.retrieveEntityList(chargesModel, null, null, null, 'chargeslist', isAppIdentity.get('jadrolog')).subscribe(data => {
      this.chargesArray = data;
      for (let i = 0; i < this.chargesArray.length; i++){
        this.chargeObj.push({'name': this.chargesArray[i].names[0].name, 'code': this.chargesArray[i].code});
      }
    });

    this.setShippmentModel();

    this.ShippmentFormGroup.get("blDate").valueChanges.subscribe(selectedValue => {
      this.ShippmentFormGroup.patchValue({ voyageYear: Number(selectedValue.substring(0, 4))}, { emitEvent: false });
    })

    if(this.input[0]){
      this.voyageCompute = this.input[0].charterType + ' ' + this.input[0].voyage + ' - ' + this.input[0].voyageYear;

      this.crudService.retrieveEntityListById(voyageCalls, this.input[0].voyageId, 'voyagecalls', isAppIdentity.get('jadrolog')).subscribe(data => {
        this.callsArrayPreliminary = data.filter( p => p.itemStatus == 'PRELIMINARY');
        this.callsArrayFinal = data.filter( p => p.itemStatus == 'FINAL');
        if(this.callsArrayFinal.length > 0){
          this.callsArray = this.callsArrayFinal;
          document.getElementById("callStatusPicker")['value'] = 'FINAL';
          for (const cols of this.gridCalls.columns) {
            if ((cols as any).field === 'nextPortDistance') {
                (cols as any).width = '10';
            }
            if ((cols as any).field === 'vesselSpeed') {
              (cols as any).width = '10';
            }
            if ((cols as any).field === 'navigationDays') {
              (cols as any).width = '10';
            }
          }
          this.gridCalls.refresh()
        }else{
          this.callsArray = this.callsArrayPreliminary;
          document.getElementById("callStatusPicker")['value'] = 'PRELIMINARY';
        }
      });

      this.crudService.retrieveEntityListById(voyageOperatorContract, this.input[0].voyageId, 'voyagecontract', isAppIdentity.get('jadrolog')).subscribe(data => {
        this.contractArray = data;
      });

      this.chargeArray = this.input[0].charge;
      this.chargeArray.sort((a, b) => (a.itemOrder < b.itemOrder ? -1 : 1));
      this.isEdit = true;
    }else{
      this.isEdit = false;
      this.initValue();
    }

    this.crudService.retrieveEntityList(voyageCargo, null, null, null, 'voyagecargo', isAppIdentity.get('jadrolog')).subscribe(data => {
      this.cargoModel = data;
      this.cargoList = this.cargoModel.map(item => item.cargoDescription).filter((value, index, self) => self.indexOf(value) === index);
    });

    this.crudService.retrieveEntityListById(voyageStatus, this.userId, 'voyagetype', isAppIdentity.get('jadrolog')).subscribe(data => {
      this.voyageTypeArray = data;
      for (let i = 0; i < this.voyageTypeArray.length; i++){
        this.voyageTypeList.push(this.voyageTypeArray[i].itemCode)
      }
    });

    this.crudService.retrieveEntityListById(customerShipper, this.userId, 'customershipper', isAppIdentity.get('jadrolog')).subscribe(data => {
      this.customerShipperArray = data;
      for (let i = 0; i < this.customerShipperArray.length; i++){
        this.customerShipper.push({'name': this.customerShipperArray[i].synonim, 'code': this.customerShipperArray[i].code});
      }
    });

    this.crudService.retrieveEntityList(setCargoType, null, null, null, 'setcargotype', isAppIdentity.get('jadrolog')).subscribe(data => {
      this.setCargoTypeArray = data;
      for(let i = 0; i < this.setCargoTypeArray.length; i++){
        this.setCargoTypeList.push({'itemCode': this.setCargoTypeArray[i].itemCode, 'itemDescription': this.setCargoTypeArray[i].itemDescription});
      }
    });

  this.chargePickParams = {
    create:()=>{
    this.chargePickElem = document.createElement('input');
        return this.chargePickElem;
    },
    read:()=>{
        return this.chargePickObj.text;
    },
    destroy:()=>{
        this.chargePickObj.destroy();
    },
    write:()=>{
        this.chargePickObj = new DropDownList({
        dataSource: this.chargeObj,
        width: 350,
        fields: { value: 'name', text: 'name' },
        value: this.initialChargeDesc,
        change: () => {
      },
      placeholder: 'Select charge',
      floatLabelType: 'Never'
      });
      this.chargePickObj.appendTo(this.chargePickElem);
  }};

  this.accountCustomerParams = {
    create:()=>{
    this.accountCustomerElem = document.createElement('input');
        return this.accountCustomerElem;
    },
    read:()=>{
        return this.accountCustomerObj.text;
    },
    destroy:()=>{
        this.accountCustomerObj.destroy();
    },
    write:()=>{
        this.accountCustomerObj = new DropDownList({
        dataSource: this.customerShipper,
        placeholder: 'Select customer',
        fields: { value: 'code', text: 'name' },
        floatLabelType: 'Never',
        value: this.initialAccountCustomer,
        width: 250,
        change: function(args){
          var formEle = document.getElementById("gridCharges").querySelector("form").ej2_instances[0];
          var accountCode = formEle.getInputElement('accountCode');
          accountCode.value = args.value;
          var shipperCode = formEle.getInputElement('shipperCode')
          shipperCode.value = args.value;
          var accountShipperCode = formEle.getInputElement('accountShipperCode');
          accountShipperCode.value = args.value;
        }.bind(this)
      });
    this.accountCustomerObj.appendTo(this.accountCustomerElem);
  }};

  this.currencyParams = {
    create:()=>{
    this.currencyElem = document.createElement('input');
        return this.currencyElem;
    },
    read:()=>{
        return this.currencyObj.text;
    },
    destroy:()=>{
        this.currencyObj.destroy();
    },
    write:()=>{
        this.currencyObj = new DropDownList({
        dataSource: this.currencyArray,
        fields: { value: 'currency', text: 'currency' },
        value: this.initialCurrency,
        width: 250,
        change: () => {
    },
    placeholder: 'Select currency',
    floatLabelType: 'Never'
    });
    this.currencyObj.appendTo(this.currencyElem);
  }};

  this.debitCreditParams = {
    create:()=>{
    this.debitCreditElem = document.createElement('input');
        return this.debitCreditElem;
    },
    read:()=>{
        return this.debitCreditObj.value;
    },
    destroy:()=>{
        this.debitCreditObj.destroy();
    },
    write:()=>{
        this.debitCreditObj = new DropDownList({
        dataSource: this.chargeTypeArray,
        placeholder: 'Debit/Credit',
        floatLabelType: 'Never',
        fields: { value: 'value', text: 'type' },
        value: this.initialDebitCredit,
        width: 250,
        change: function(args){
          var formEle = document.getElementById("gridCharges").querySelector("form").ej2_instances[0];
          var debitCredit = formEle.getInputElement('debitFlag');
          var creditAmount = formEle.getInputElement('invoiceAmountCredit');
          var debitAmount = formEle.getInputElement('invoiceAmountDebit');
          let debitCreditValue = debitCredit.value;
          if(debitCreditValue == '1'){
            creditAmount.value = null;
            creditAmount.disabled = true;
            debitAmount.disabled = false;
          }else{
            debitAmount.value = null;
            debitAmount.disabled = true;
            creditAmount.disabled = false;
          }
        }.bind(this)
      });
    this.debitCreditObj.appendTo(this.debitCreditElem);
  }};

  this.setCargoTypeEdit = {
    create:()=>{
    this.setCargoTypeElem = document.createElement('input');
        return this.setCargoTypeElem;
    },
    read:()=>{
        return this.setCargoTypeObj.text;
    },
    destroy:()=>{
        this.setCargoTypeObj.destroy();
    },
    write:()=>{
        this.setCargoTypeObj = new DropDownList({
        dataSource: this.setCargoTypeList,
        placeholder: 'Select a cargo',
        floatLabelType: 'Never',
        fields: { value: 'itemCode', text: 'itemDescription' },
        width: 250,
        value: this.initialCargoType, 
        change: function(args){
          var formEle = document.getElementById("gridCharges").querySelector("form").ej2_instances[0];
          var cargoTypeCode = formEle.getInputElement('cargoType');
          cargoTypeCode.value = args.value;
        }.bind(this)
      });
    this.setCargoTypeObj.appendTo(this.setCargoTypeElem);
    }};
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

  initObjects() {
    this.ShippmentFormGroup = null;
  }

  setShippmentModel(){
    this.isDataChanged = true;
    if (!this.ShippmentFormGroup) {
      this.initObjects();
      if(this.input[0]){
        this.buildFormGroup(this.input[0]);
      }else{
        this.buildFormGroup(this.input);
        this.ShippmentFormGroup.patchValue({ changed: true }, { emitEvent: false });
      }
      // form changes
      this.subscription.add(this.ShippmentFormGroup.valueChanges.subscribe(() => {
        this.ShippmentFormGroup.patchValue({ changed: true }, { emitEvent: false });
      })
      );
    }
  }

  saveShippment() {

    let vesselModel: VesselModel;
    vesselModel = new VesselModel();
    var errorMessage = '';

    let callsData: Object = (this.gridCalls.getCurrentViewRecords()) as VoyageCallsModel[];

    let chargeData: Object = (this.gridCharges.getCurrentViewRecords()) as VoyageOperatorChargeModel[];

    let contractData: Object = (this.gridContract.getCurrentViewRecords()) as VoyageOperatorContractModel[];

    let ShippmentModel = (this.ShippmentFormGroup as FormGroup).getRawValue() as VoyageOverviewModel;

    vesselModel = ShippmentModel.vessel[0] as VesselModel;

    ShippmentModel.vessel = vesselModel;

    ShippmentModel.changed = true;

    try {

      if (ShippmentModel.changed) {
        let allOk: boolean = true;

        if (!ShippmentModel.vesselCode) {
          errorMessage += 'Missing Vessel.\r\n';
          allOk = false;
        }
        if (!ShippmentModel.charterType) {
          errorMessage += 'Missing Voyage Type.\r\n';
          allOk = false;
        }
        if (!ShippmentModel.lineCode) {
          errorMessage += 'Missing Market.\r\n';
          allOk = false;
        }
        if (!ShippmentModel.blDate) {
          errorMessage += 'Missing BL Date.\r\n';
          allOk = false;
        }
        if (!ShippmentModel.charterStatus) {
          errorMessage += 'Missing Charter Status.\r\n';
          allOk = false;
        }
        if (!ShippmentModel.cargoDescription) {
          errorMessage += 'Missing Cargo Description.\r\n';
          allOk = false;
        }

        if (allOk) {
          this.crudService.doActionOfPostType(ShippmentModel.voyageId, 'shippmentlist', null, ShippmentModel, isAppIdentity.get('jadrolog'))
            .subscribe(data => {
          });
          if((callsData as object[]).length > 0){
            this.crudService.doActionOfPostType(ShippmentModel.voyageId, 'callslist', null, callsData, isAppIdentity.get('jadrolog'))
              .subscribe(data => {
            });
          }
          if((chargeData as object[]).length > 0){
            this.crudService.doActionOfPostType(ShippmentModel.voyageId, 'chargelist', null, chargeData, isAppIdentity.get('jadrolog'))
            .subscribe(data => {
            });
          }
          if((contractData as object[]).length > 0){
            this.crudService.doActionOfPostType(ShippmentModel.voyageId, 'contractlist', null, contractData, isAppIdentity.get('jadrolog'))
            .subscribe(data => { 
            }); 
          }
          this.retireveAfterClose = true;
          this.isDataChanged = false;
          const modalRef = this.modalService.open(ConfirmationDialogComponent);
          modalRef.componentInstance.confirmQuestion = 'Shipment successfully saved !'
//          return this.output.emit(true); 
        }
        else {
          if (errorMessage) {
            throw new Error(errorMessage);
          }
        }
      }
      else {
        this.output.emit(null);
      }
    }
    catch (e) {
      if (e instanceof Error) {
        alert(e.message);
        return;
      }
    }
  }

  cancelChanges() {
    // Need to check if there was any changes. If wasn't the program needs to go out from edit form. If the form was changed, need to ask user if he want to save that changes.
    let msg = "Data not saved. Do you want to save changes?"
    let ShippmentModel = (this.ShippmentFormGroup as FormGroup).getRawValue() as VoyageOverviewModel;
    //ShippmentModel.changed = false;
    if (this.isDataChanged){
      const modalRef = this.modalService.open(ConfirmDialogComponent);
      modalRef.componentInstance.confirmQuestion = msg;
      modalRef.result.then((result) => {
      if (result == true) {
        this.saveShippment()
        this.output.emit(true);
      }
      else{
        this.output.emit(this.retireveAfterClose);
      }
    }).catch((error) => {
      console.log(error);
    }); 
    }
    else{
      this.output.emit(this.retireveAfterClose);
    }
  }

  addVessel(){
    let vesselModel = new VesselModel();
    const modalRef = this.modalService.open(BaseDialogComponent, { windowClass: 'modalDialogClass' });
    modalRef.componentInstance.childItem = new DialogChildItem(VesselChooseFormComponent, vesselModel);
    modalRef.result.then(changesSavedOk => {
      if (changesSavedOk) {
        this.vesselName = changesSavedOk[0].name;
        this.vesselCode = changesSavedOk[0].code;
        this.vesselId = changesSavedOk[0].vesselId;
        this.vesselSpeed = changesSavedOk[0].speedAvg;
        this.vessel().patchValue([
          {name: this.vesselName,
          code: this.vesselCode}
        ]);
        this.ShippmentFormGroup.controls['vesselCode'].setValue(this.vesselCode);
        this.ShippmentFormGroup.controls['voyagecode'].setValue(this.vesselCode);
        this.ShippmentFormGroup.controls['vesselId'].setValue(this.vesselId);
        this.ShippmentFormGroup.controls['vesselSpeed'].setValue(this.vesselSpeed);
        this.isDataChanged = true;
      }
    }).catch(error => {
      console.log(error);
    });
  }

  buildFormGroup(model: VoyageOverviewModel){

      let charge = model.charge;
      let vessel = model.vessel;

      this.ShippmentFormGroup = this.fb.group({
        position: model.position, 
        added: model.added, 
        deleted: model.deleted, 
        changed: model.changed, 
        selected: model.selected,
        voyageId: model.voyageId, 
        voyagecode: model.vesselCode,
        vesselId: model.vesselId, 
        voyage: model.voyage,
        status: model.status,
        voyageYear: model.voyageYear,
        vesselCode: model.vesselCode,
        lineCode: model.lineCode, 
        userId: model.userId,
        date: model.date,
        lineId: model.lineId,
        voyageDirection: model.voyageDirection,
        operation: model.operation, 
        charterStatus: model.charterStatus,
        pol: model.pol,
        pod: model.pod,
        charterType: model.charterType, 
        cargoDescription: model.cargoDescription, 
        cargoWeight: model.cargoWeight,
        cargoM3: model.cargoM3,
        freightAmount: model.freightAmount,
        freightStatus: model.freightStatus,
        blDate: model.blDate, 
        blStatus: model.blStatus,
        freightCommision: model.freightCommision,
        operatorCode: model.operatorCode, 
        suboperatorCode: model.suboperatorCode,
        suboperatorStatus: model.suboperatorStatus,
        operatorFreight: model.operatorFreight,
        suboperatorFreight: model.suboperatorFreight, 
        operatorCommision: model.operatorCommision, 
        suboperatorCommision: model.suboperatorCommision, 
        vesselSpeed: model.vesselSpeed, 
        volp: model.volp, 
        firstEta: model.firstEta, 
        firstEtd: model.firstEtd, 
        operatorCurrency: model.operatorCurrency, 
        vesselCharterView: model.vesselCharterView, 
        quantity: model.quantity, 
        voyageType: model.voyageType, 
         
        charge: this.fb.array([]), 
        vessel: this.fb.array([]),
        
        chargeTotal: model.chargeTotal
      });

      for(let i = 0; i < charge.length; i++){
        this.charge().push(this.newCharge(charge[i]));
      }

      this.vessel().push(this.newVessel(vessel));
  }

  charge(): FormArray {
    return this.ShippmentFormGroup.get("charge") as FormArray
  }

  newCharge(model: VoyageOperatorChargeModel): FormGroup {
    return this.fb.group({
      itemId: model.itemId,
      voyageId: model.voyageId,
      operatorCode: model.operatorCode,
      operatorType: model.operatorType,
      chargeCode: model.chargeCode,
      invoiceNumber: model.invoiceNumber, 
      invoiceType: model.invoiceType, 
      invoiceDate: model.invoiceDate,
      invoiceStatus: model.invoiceStatus, 
      invoiceAmountCredit: model.invoiceAmountCredit, 
      invoiceAmountDebit: model.invoiceAmountDebit, 
      commisionRate: model.commisionRate, 
      commisionAmount: model.commisionAmount, 
      shipperCode: model.shipperCode, 
      itemOperation: model.itemOperation, 
      lumpsumAmount: model.lumpsumAmount, 
      chargeRate: model.chargeRate, 
      itemOrder: model.itemOrder, 
      invoiceReceiver: model.invoiceReceiver, 
      invoiceId: model.invoiceId, 
      operatorContractId: model.operatorContractId, 
      chargeDesc: model.chargeDesc, 
      itemStatus: model.itemStatus, 
      currencyCode: model.currencyCode, 
      polCode: model.polCode, 
      polName: model.polName, 
      podCode: model.podCode, 
      podName: model.podName, 
      totalFlag: model.totalFlag, 
      operatorRefCode: model.operatorRefCode,
      debitFlag: model.debitFlag, 
      cargoType: model.cargoType,
      shpView: model.shpView, 
      tcView: model.tcView, 
      remark: model.remark, 
      accountCode: model.accountCode, 
      accountShipperCode: model.accountShipperCode, 
      ntceView: model.ntceView,
      customer: model.customer, 
      customerReceiver: model.customerReceiver
    });
  }

  vessel(): FormArray {
    return this.ShippmentFormGroup.get("vessel") as FormArray
  }

  newVessel(model: VesselModel): FormGroup {
    return this.fb.group({
      vesselId: model.vesselId, 
      code: model.code, 
      name: model.name, 
      owner: model.owner, 
      status: model.status, 
      dateInserted: model.dateInserted,
      userId: model.userId, 
      vslType: model.vslType, 
      vslLength: model.vslLength, 
      vslBreadth: model.vslBreadth, 
      vslDraught: model.vslDraught, 
      gt: model.gt, 
      dwt: model.dwt, 
      speedMax: model.speedMax, 
      speedAvg: model.speedAvg, 
      hatchNo: model.hatchNo, 
      gearNo: model.gearNo, 
      flagCode: model.flagCode, 
      callSign: model.callSign, 
      imoSign: model.imoSign, 
      mmsiSign: model.mmsiSign, 
      vslM3: model.vslM3, 
      build: model.build, 
      vslMt: model.vlsMt, 
      vesselClass: model.vesselClass, 
      vesselAliasCode: model.vesselAliasCode, 
      vslConsumption: model.vslConsumption
    });
  }

  initValue(){
    this.ShippmentFormGroup.controls["lineCode"].setValue("NA");
    this.ShippmentFormGroup.controls["charterStatus"].setValue("CONFIRMED");
    this.ShippmentFormGroup.controls["charterType"].setValue("ACCR");
    this.ShippmentFormGroup.controls["freightCommision"].setValue(2.5);
  }

  addCalls(){
    let callStatus: String = '';

    if(this.ShippmentFormGroup.value['voyageId'] == null){
      window.alert('Invalid voyage or voyage not saved!');
      return;
    }

    callStatus = document.getElementById("callStatusPicker")['value'];
    
    if((this.gridCalls.currentViewData as object[]).length > 0){
      if(!this.gridCalls.currentViewData[this.selectedCallIndex[0]]['callId']){
        this.gridCalls.dataSource[this.selectedCallIndex[0]['operationCode']] = this.gridCalls.currentViewData[this.selectedCallIndex[0]]['operationCode']
        this.gridCalls.dataSource[this.selectedCallIndex[0]]['portName'] = this.gridCalls.currentViewData[this.selectedCallIndex[0]]['portName'];
        this.gridCalls.dataSource[this.selectedCallIndex[0]]['portCode'] = this.gridCalls.currentViewData[this.selectedCallIndex[0]]['portCode'];
        this.gridCalls.dataSource[this.selectedCallIndex[0]]['portDays'] = this.gridCalls.currentViewData[this.selectedCallIndex[0]]['portDays'];
        this.gridCalls.dataSource[this.selectedCallIndex[0]]['eta'] = this.gridCalls.currentViewData[this.selectedCallIndex[0]]['eta'];
        this.gridCalls.dataSource[this.selectedCallIndex[0]]['etd'] = this.gridCalls.currentViewData[this.selectedCallIndex[0]]['etd'];
      }
      const rdata: object = { operationCode: 'Loading', portName: '', portDays: 0, eta: new Date(), etd: new Date(), voyageId: this.input[0].voyageId, loadCountry: 'XX', loadPort: 'XXX', destCountry: 'XX', destPort: 'XXX', itemStatus:callStatus, portCallOrder: this.selectedCallIndex[0] + 2};
      (this.gridCalls.dataSource as object[]).splice(this.selectedCallIndex[0] + 1, 0, rdata);
      for(let i = this.selectedCallIndex[0] + 2; i < (this.gridCalls.dataSource as object[]).length; i++){
        this.gridCalls.dataSource[i]['portCallOrder'] = i + 1;
      }
    }else{
      const rdata: object = { operationCode: 'Loading', portName: '', portDays: 0, eta: new Date(), etd: new Date(), voyageId: this.input[0].voyageId, loadCountry: 'XX', loadPort: 'XXX', destCountry: 'XX', destPort: 'XXX', itemStatus:callStatus, portCallOrder: 1};
      (this.gridCalls.dataSource as object[]).splice(0, 0, rdata);
    }
    this.isDataChanged = true;
    this.ShippmentFormGroup.patchValue({ changed: true }, { emitEvent: false });
    this.gridCalls.refresh();
  }

  deleteCalls(){
    let selectedRow: Object = (this.gridCalls.getSelectedRecords()[0]);
    const selectedRowIndex: number = this.gridCalls.getSelectedRowIndexes()[0];
    let callId: number = selectedRow['callId'];
    if(callId){
      if (this.gridCalls.getSelectedRowIndexes().length) {
        let msg = "Please confirm delete operation? \n Proceed with the operation?";
        const modalRef = this.modalService.open(ConfirmDialogComponent);
        modalRef.componentInstance.confirmQuestion = msg;
        modalRef.result.then((result) => {
          if (result == true) {
            (this.gridCalls.dataSource as object[]).splice(selectedRowIndex, 1);
            this.gridCalls.refresh();
            this.crudService.deleteSingleEntity(callId, 'voyagecalls', isAppIdentity.get('jadrolog')).subscribe(() => {
              alert('Item deleted successfully.');
            });
          }
        }).catch((error) => {
          console.log(error);
        });
      } else {
        alert('No selected call for delete operation.');
      }
    }else{
      (this.gridCalls.dataSource as object[]).splice(selectedRowIndex, 1);
      this.gridCalls.refresh();
    }
  }

  addCharges(){

    if(this.ShippmentFormGroup.value['voyageId'] == null){
      window.alert('Invalid voyage or voyage not saved!');
      return;
    }

    if((this.gridCharges.currentViewData as object[]).length > 0){
      let selectedRow: object = (this.gridCharges.getSelectedRecords()[0]);
      let newFromTo =new Object();
      Object.assign(newFromTo, selectedRow['customerReceiver']);

      const rdata: object = {accountCode: selectedRow['accountCode'], accountShipperCode: selectedRow['accountShipperCode'], chargeCode: selectedRow['chargeCode'], chargeDesc: selectedRow['chargeDesc'], 
      commisionAmount: selectedRow['commisionAmount'], commisionRate: selectedRow['commisionRate'], currencyCode: selectedRow['currencyCode'], customer: selectedRow['customer'], customerReceiver: newFromTo, debitFlag: selectedRow['debitFlag'], 
      invoiceAmountCredit: selectedRow['invoiceAmountCredit'], invoiceAmountDebit: selectedRow['invoiceAmountDebit'], invoiceReceiver: selectedRow['invoiceReceiver'], itemOrder: this.selectedChargeIndex[0] + 2, itemStatus: selectedRow['itemStatus'], operatorCode: selectedRow['operatorCode'], 
      shipperCode: selectedRow['shipperCode'], shpView: selectedRow['shpView'], tcView: selectedRow['tcView'], voyageId: selectedRow['voyageId']};

      this.gridCharges.dataSource = this.gridCharges.currentViewData;
      
      (this.gridCharges.dataSource as object[]).splice(this.selectedChargeIndex[0] + 1, 0, rdata);

      for(let i = this.selectedChargeIndex[0] + 2; i < (this.gridCharges.currentViewData as object[]).length; i++){
        this.gridCharges.currentViewData[i]['itemOrder'] = i + 1;
      }
    }else{
      let newCustomerAccount: CustomerShipperChargeModel = new CustomerShipperChargeModel();
      let newFromTo: CustomerShipperChargeModel = new CustomerShipperChargeModel();
      const rdata: object = { chargeCode: 'FREIGHT', chargeDesc: 'Freight', shpView: 1, tcView: 1, 
      invoiceAmountDebit: this.ShippmentFormGroup.value['freightAmount'], commisionRate: this.ShippmentFormGroup.value['freightCommision'], 
      commisionAmount: Number(this.ShippmentFormGroup.value['freightAmount'] * this.ShippmentFormGroup.value['freightCommision'] / 100), 
      accountShipperCode: 'JADROLOG', accountCode: 'JADROLOG', shipperCode: 'JADROLOG', voyageId: this.ShippmentFormGroup.value['voyageId'], 
      operatorCode: 'OPERATOR', itemOrder: 1, invoiceAmountCredit: null, invoiceReceiver: 'JADROLOG', customer: newCustomerAccount, 
      customerReceiver: newFromTo, currencyCode: 'EUR', debitFlag: 1};
      (this.gridCharges.dataSource as object[]).splice(0, 0, rdata);
    }
    this.isDataChanged = true;
    this.ShippmentFormGroup.patchValue({ changed: true }, { emitEvent: false });
    this.gridCharges.refresh();
  }

  deleteCharge(args: any){
    let selectedRow: Object = (this.gridCharges.getSelectedRecords()[0]);
    var deleteArray: Array<number> = [];

    let _i: number = 0;
    if (selectedRow === undefined){
      for (_i; _i < this.gridCharges.currentViewData.length; _i++){
        if (this.gridCharges.currentViewData[Number(_i)]['itemOperation'] == 1){
          deleteArray.push( Number(this.gridCharges.currentViewData[Number(_i)]['itemId']));
          //this.indexArray.push( Number(this.gridCharges.currentViewData[Number(_i)]));
        }
      }

      let msg = "Please confirm delete operation? \n Proceed with the operation?";
      const modalRef = this.modalService.open(ConfirmDialogComponent);
      modalRef.componentInstance.confirmQuestion = msg;
      modalRef.result.then((result) => {
        if (result == true) {
          for (_i = 0; _i < deleteArray.length; _i++){
            (this.gridCharges.dataSource as object[]).splice(this.indexArray[_i], 1);
            this.gridCharges.refresh();
            this.crudService.deleteSingleEntity(deleteArray[_i], 'chargelist', isAppIdentity.get('jadrolog')).subscribe(() => {            
            });
          }
        }
        this.gridCharges.refresh();
        const modalRef = this.modalService.open(ConfirmationDialogComponent);
        modalRef.componentInstance.confirmQuestion = 'Charges deleted successfully!'
      })
    }
    else{
      const selectedRowIndex: number = this.gridCharges.getSelectedRowIndexes()[0];
      let chargeId: number = selectedRow['itemId'];
      if(chargeId){
        if (this.gridCharges.getSelectedRowIndexes().length) {
          let msg = "Please confirm delete operation? \n Proceed with the operation?";
          const modalRef = this.modalService.open(ConfirmDialogComponent);
          modalRef.componentInstance.confirmQuestion = msg;
          modalRef.result.then((result) => {
            if (result == true) {
              (this.gridCharges.dataSource as object[]).splice(selectedRowIndex, 1);
              this.gridCharges.refresh();
              this.crudService.deleteSingleEntity(chargeId, 'chargelist', isAppIdentity.get('jadrolog')).subscribe(() => {
                const modalRef = this.modalService.open(ConfirmationDialogComponent);
                modalRef.componentInstance.confirmQuestion = 'Charge deleted successfully !'
              });
            }
          }).catch((error) => {
            console.log(error);
          });
        } else {
          alert('No selected charge for delete operation.');
        }
      }else{
        (this.gridCharges.dataSource as object[]).splice(selectedRowIndex, 1);
        this.gridCharges.refresh();
      }
    }
    this.isDataChanged = true;
  }
  
  cellCallsEdit(args) {
    if (args.columnName == 'portDays') {
      args.cancel = true;
    }
  }

  rowSelectedCalls(args: RowSelectEventArgs) {
    this.selectedRowCalls = this.gridCalls.getSelectedRecords();
    this.selectedCallIndex = this.gridCalls.getSelectedRowIndexes();
  }

  rowSelectedCharge(args: RowSelectEventArgs) {
    this.selectedRowCharge = this.gridCharges.getSelectedRecords();
    this.selectedChargeIndex = this.gridCharges.getSelectedRowIndexes();
  }

  addVoyageOperations(){
    this.gridCalls.dataSource = this.gridCalls.currentViewData;
    let selectedCall: VoyageCallsModel;
    let ErrorMessage = ''
    let allOk: boolean = true;

    if(document.getElementById("callStatusPicker")['value'] == 'PRELIMINARY'){
      alert('This operation is not allowed for PRELIMINARY state.');
      return;
    }

    selectedCall = this.selectedRowCalls as VoyageCallsModel;

    if(!selectedCall){
      ErrorMessage += 'You need to select one call.'
      allOk = false;
    }

    if(!selectedCall[0].callId){
      ErrorMessage += 'You need to save call firstly.'
      allOk = false;
    }

    if (!allOk) {
      window.alert(ErrorMessage);
      return;
    }

    const modalRef = this.modalService.open(BaseDialogComponent, { windowClass: 'modalDialogClass' });
    modalRef.componentInstance.childItem = new DialogChildItem(VoyageOperationsFormComponent, selectedCall);
    modalRef.result.then(changesSavedOk => {
      if (changesSavedOk) {
        for(let i = 0; i < this.gridCalls.currentViewData.length; i++){
          if(i != this.selectedCallIndex[0]){
            this.gridCalls.dataSource[i]['operationCode'] = this.gridCalls.currentViewData[i]['operationCode'];
            this.gridCalls.dataSource[i]['portName'] = this.gridCalls.currentViewData[i]['portName'];
            this.gridCalls.dataSource[i]['portDays'] = this.gridCalls.currentViewData[i]['portDays'];
            this.gridCalls.dataSource[i]['eta'] = this.gridCalls.currentViewData[i]['eta'];
            this.gridCalls.dataSource[i]['etd'] = this.gridCalls.currentViewData[i]['etd'];
            this.gridCalls.dataSource[i]['operationAnchored'] = this.gridCalls.currentViewData[i]['operationAnchored'];
            this.gridCalls.dataSource[i]['operationMoored'] = this.gridCalls.currentViewData[i]['operationMoored'];
            this.gridCalls.dataSource[i]['operationStartWork'] = this.gridCalls.currentViewData[i]['operationStartWork'];
            this.gridCalls.dataSource[i]['operationEndWork'] = this.gridCalls.currentViewData[i]['operationEndWork'];
            this.gridCalls.dataSource[i]['operationSailed'] = this.gridCalls.currentViewData[i]['operationSailed'];
            this.gridCalls.dataSource[i]['totalWorked'] = this.gridCalls.currentViewData[i]['totalWorked'];
            this.gridCalls.dataSource[i]['totalIdle'] = this.gridCalls.currentViewData[i]['totalIdle'];
          }else{
            if(selectedCall.operationCode == 'Balast'){
              let daysDiff = (new Date(changesSavedOk.etd).getTime() - new Date(changesSavedOk.eta).getTime())/1000/60/60/24;
              this.gridCalls.dataSource[i]['portDays'] = daysDiff;
            }else{
              let daysDiff = 0;
              this.gridCalls.dataSource[i]['portDays'] = daysDiff;
            }
            this.gridCalls.dataSource[i]['operationCode'] = this.gridCalls.currentViewData[i]['operationCode'];
            this.gridCalls.dataSource[i]['portName'] = this.gridCalls.currentViewData[i]['portName'];
            this.gridCalls.dataSource[i]['eta'] = changesSavedOk.operationAnchored;
            this.gridCalls.dataSource[i]['etd'] = changesSavedOk.operationSailed;
            this.gridCalls.dataSource[i]['operationAnchored'] = changesSavedOk.operationAnchored;
            this.gridCalls.dataSource[i]['operationMoored'] = changesSavedOk.operationMoored;
            this.gridCalls.dataSource[i]['operationStartWork'] = changesSavedOk.operationStartWork;
            this.gridCalls.dataSource[i]['operationEndWork'] = changesSavedOk.operationEndWork;
            this.gridCalls.dataSource[i]['operationSailed'] = changesSavedOk.operationSailed;
            this.gridCalls.dataSource[i]['totalWorked'] = changesSavedOk.totalWorked;
            this.gridCalls.dataSource[i]['totalIdle'] = changesSavedOk.totalIdle;
          }
        }
        if(this.selectedCallIndex[0] != (this.gridCalls.currentViewData.length - 1)){
          var datetime1 = changesSavedOk.operationSailed;
          var datetime2 = this.gridCalls.currentViewData[this.selectedCallIndex[0] + 1]['eta'];
          var navDays = this.getNavigationDays(new Date(datetime1), new Date(datetime2));
          this.gridCalls.dataSource[this.selectedCallIndex[0]]['navigationDays'] = navDays;
          this.gridCalls.dataSource[this.selectedCallIndex[0]]['vesselSpeed'] = this.gridCalls.currentViewData[this.selectedCallIndex[0]]['nextPortDistance'] / (navDays * 24);
          if(this.selectedCallIndex[0] != 0){
            datetime1 = this.gridCalls.currentViewData[this.selectedCallIndex[0] - 1]['etd'];
            datetime2 = changesSavedOk.eta;
            navDays = this.getNavigationDays(new Date(datetime1), new Date(datetime2));
            this.gridCalls.dataSource[this.selectedCallIndex[0] - 1]['navigationDays'] = navDays;
            this.gridCalls.dataSource[this.selectedCallIndex[0] - 1]['vesselSpeed'] = this.gridCalls.currentViewData[this.selectedCallIndex[0] - 1]['nextPortDistance'] / (navDays * 24);
          }
        }
        if(this.gridCalls.currentViewData[this.selectedCallIndex[0]]['operationCode'] != 'Balast'){
          this.gridCalls.dataSource[this.selectedCallIndex[0]]['portDays'] = (new Date(this.gridCalls.currentViewData[this.selectedCallIndex[0]]['etd']).getTime() - (new Date(this.gridCalls.currentViewData[this.selectedCallIndex[0]]['eta']).getTime())) / 1000/60/60/24;
        }
        this.ShippmentFormGroup.patchValue({ changed: true }, { emitEvent: false });
        this.isDataChanged = true;
        this.gridCalls.refresh();
      }
    }).catch(error => {
      console.log(error);
    });
  }   

  addPort(args){

    let selectedCall: VoyageCallsModel;
    let ErrorMessage = ''
    let allOk: boolean = true;

    selectedCall = this.selectedRowCalls as VoyageCallsModel;

    if(!selectedCall){
      ErrorMessage += 'You need to select one call.'
      allOk = false;
    }

    if (!allOk) {
      window.alert(ErrorMessage);
      return;
    }

    const modalRef = this.modalService.open(BaseDialogComponent, { windowClass: 'modalDialogClass' });
    modalRef.componentInstance.childItem = new DialogChildItem(PortChooseFormComponent, '');
    modalRef.result.then(changesSavedOk => {
      if (changesSavedOk) {
        var formEle = document.getElementById("gridCalls").querySelector("form").ej2_instances[0];
        var portCode = formEle.getInputElement('portCode');
        portCode.value = changesSavedOk[0].code;
        var portNameBox = formEle.getInputElement('input');
        portNameBox.value = changesSavedOk[0].name;
        this.portNameChanged = true;
        this.portNameChangedName = changesSavedOk[0].name;

        if(document.getElementById("callStatusPicker")['value'] == 'FINAL'){
          if (this.selectedCallIndex[0] != (this.gridCalls.currentViewData.length - 1)){
            var startPort = changesSavedOk[0].code;
            var destinationPort = this.gridCalls.currentViewData[this.selectedCallIndex[0] + 1]['portCode'];
            var ports = [];
            var type: VoyageCallsModel;
            ports.push(startPort);
            ports.push(destinationPort);

            this.crudService.retrieveEntityListByPath(type, null, 'getdistance', ports, isAppIdentity.get('jadrolog')).subscribe(data => {
              var distanceField = formEle.getInputElement('nextPortDistance');
              distanceField.value = data;
            });

            if(this.selectedCallIndex[0] != 0){
              startPort = this.gridCalls.currentViewData[this.selectedCallIndex[0] - 1]['portCode'];
              destinationPort = changesSavedOk[0].code;
              ports = [];
              ports.push(startPort);
              ports.push(destinationPort);

              this.crudService.retrieveEntityListByPath(type, null, 'getdistance', ports, isAppIdentity.get('jadrolog')).subscribe(data => {
                // var formEle = document.getElementById("gridCalls").querySelector("form").ej2_instances[0];
                this.gridCalls.dataSource[this.selectedCallIndex[0] - 1]['nextPortDistance'] = data;
              });
            }
          }
        }
      }
    }).catch(error => {
      console.log(error);
    });
  }

  rowSelectedContract(args: RowSelectEventArgs) {
    this.selectedRowContract = this.gridContract.getSelectedRecords();
    this.selectedContractIndex = this.gridContract.getSelectedRowIndexes();
  }

  editContract(){
    let selectedContract: VoyageOperatorContractModel;
    let ErrorMessage = ''
    let allOk: boolean = true;
    let paramArray = [];

    selectedContract = this.selectedRowContract as VoyageOperatorContractModel;

    paramArray.push(selectedContract);
    paramArray.push(this.input[0]);

    if(!selectedContract){
      ErrorMessage += 'You need to select one contract.'
      allOk = false;
    }

    if (!allOk) {
      window.alert(ErrorMessage);
      return;
    }

    const modalRef = this.modalService.open(BaseDialogComponent, { windowClass: 'modalDialogClass' });
    modalRef.componentInstance.childItem = new DialogChildItem(ContractFormComponent, paramArray);
    modalRef.result.then(changesSavedOk => {
      if (changesSavedOk) {
        for(let i = 0; i < this.gridContract.currentViewData.length; i++){
          if(i != this.selectedContractIndex[0]){
            this.gridContract.dataSource[i]['itemId'] = this.gridContract.currentViewData[i]['itemId'];
            this.gridContract.dataSource[i]['voyageId'] = this.gridContract.currentViewData[i]['voyageId'];
            this.gridContract.dataSource[i]['contractNumber'] = this.gridContract.currentViewData[i]['contractNumber'];
            this.gridContract.dataSource[i]['polCode'] = this.gridContract.currentViewData[i]['polCode'];
            this.gridContract.dataSource[i]['podCode'] = this.gridContract.currentViewData[i]['podCode'];
            this.gridContract.dataSource[i]['volumeAmount'] = this.gridContract.currentViewData[i]['volumeAmount'];
            this.gridContract.dataSource[i]['weightAmount'] = this.gridContract.currentViewData[i]['weightAmount'];
            this.gridContract.dataSource[i]['priceRate'] = this.gridContract.currentViewData[i]['priceRate'];
            this.gridContract.dataSource[i]['priceUnit'] = this.gridContract.currentViewData[i]['priceUnit'];
            this.gridContract.dataSource[i]['operatorCode'] = this.gridContract.currentViewData[i]['operatorCode'];
            this.gridContract.dataSource[i]['operatorType'] = this.gridContract.currentViewData[i]['operatorType'];
            this.gridContract.dataSource[i]['loadStatus'] = this.gridContract.currentViewData[i]['loadStatus'];
            this.gridContract.dataSource[i]['polName'] = this.gridContract.currentViewData[i]['polName'];
            this.gridContract.dataSource[i]['podName'] = this.gridContract.currentViewData[i]['podName'];
            this.gridContract.dataSource[i]['lumpsumAmount'] = this.gridContract.currentViewData[i]['lumpsumAmount'];
            this.gridContract.dataSource[i]['itemOrder'] = this.gridContract.currentViewData[i]['itemOrder'];
            this.gridContract.dataSource[i]['cargoType'] = this.gridContract.currentViewData[i]['cargoType'];
            this.gridContract.dataSource[i]['volpAmount'] = this.gridContract.currentViewData[i]['volpAmount'];
            this.gridContract.dataSource[i]['buyerCode'] = this.gridContract.currentViewData[i]['buyerCode'];
            this.gridContract.dataSource[i]['buyerId'] = this.gridContract.currentViewData[i]['buyerId'];
            this.gridContract.dataSource[i]['chargeAmount'] = this.gridContract.currentViewData[i]['chargeAmount'];
            this.gridContract.dataSource[i]['currencyCode'] = this.gridContract.currentViewData[i]['currencyCode'];
            this.gridContract.dataSource[i]['chartererCode'] = this.gridContract.currentViewData[i]['chartererCode'];
            this.gridContract.dataSource[i]['quantity'] = this.gridContract.currentViewData[i]['quantity'];
          }else{
            this.gridContract.dataSource[i]['itemId'] = changesSavedOk.itemId;
            this.gridContract.dataSource[i]['voyageId'] = changesSavedOk.voyageId;
            this.gridContract.dataSource[i]['contractNumber'] = changesSavedOk.contractNumber;
            this.gridContract.dataSource[i]['polCode'] = changesSavedOk.polCode;
            this.gridContract.dataSource[i]['podCode'] = changesSavedOk.podCode;
            this.gridContract.dataSource[i]['volumeAmount'] = changesSavedOk.volumeAmount;
            this.gridContract.dataSource[i]['weightAmount'] = changesSavedOk.weightAmount;
            this.gridContract.dataSource[i]['priceRate'] = changesSavedOk.priceRate;
            this.gridContract.dataSource[i]['priceUnit'] = changesSavedOk.priceUnit;
            this.gridContract.dataSource[i]['operatorCode'] = changesSavedOk.operatorCode;
            this.gridContract.dataSource[i]['operatorType'] = changesSavedOk.operatorType;
            this.gridContract.dataSource[i]['loadStatus'] = changesSavedOk.loadStatus;
            this.gridContract.dataSource[i]['polName'] = changesSavedOk.polName;
            this.gridContract.dataSource[i]['podName'] = changesSavedOk.podName;
            this.gridContract.dataSource[i]['lumpsumAmount'] = changesSavedOk.lumpsumAmount;
            this.gridContract.dataSource[i]['itemOrder'] = changesSavedOk.itemOrder;
            this.gridContract.dataSource[i]['cargoType'] = changesSavedOk.cargoType;
            this.gridContract.dataSource[i]['volpAmount'] = changesSavedOk.volpAmount;
            this.gridContract.dataSource[i]['buyerCode'] = changesSavedOk.buyerCode;
            this.gridContract.dataSource[i]['buyerId'] = changesSavedOk.buyerId;
            this.gridContract.dataSource[i]['chargeAmount'] = changesSavedOk.chargeAmount;
            this.gridContract.dataSource[i]['currencyCode'] = changesSavedOk.currencyCode;
            this.gridContract.dataSource[i]['chartererCode'] = changesSavedOk.chartererCode;
            this.gridContract.dataSource[i]['quantity'] = changesSavedOk.quantity;
          }
        }
        this.isDataChanged = true;
        this.gridContract.refresh();
      }
    }).catch(error => {
      console.log(error);
    });
  }

  addContract(){

    if(this.ShippmentFormGroup.value['voyageId'] == null){
      window.alert('Invalid voyage or voyage not saved!');
      return;
    }

    let paramArray = [];
    let newContract: VoyageOperatorContractModel;
    newContract = new VoyageOperatorContractModel();

    paramArray.push(newContract);
    paramArray.push(this.input[0]);

    const modalRef = this.modalService.open(BaseDialogComponent, { windowClass: 'modalDialogClass' });
    modalRef.componentInstance.childItem = new DialogChildItem(ContractFormComponent, paramArray);
    modalRef.result.then(changesSavedOk => {
      if (changesSavedOk) {
        const rdata: object = { itemId: changesSavedOk.itemId, voyageId: this.ShippmentFormGroup.value['voyageId'], contractNumber: changesSavedOk.contractNumber, polCode: changesSavedOk.polCode, podCode: changesSavedOk.podCode, 
        volumeAmount: changesSavedOk.volumeAmount, weightAmount: changesSavedOk.weightAmount, priceRate: changesSavedOk.priceRate, priceUnit: changesSavedOk.priceUnit, operatorCode: changesSavedOk.operatorCode, 
        operatorType: 'OPERATOR', loadStatus: changesSavedOk.loadStatus, polName: changesSavedOk.polName, podName: changesSavedOk.podName, lumpsumAmount: changesSavedOk.lumpsumAmount, itemOrder: this.gridContract.currentViewData.length + 1, 
        cargoType: changesSavedOk.cargoType, volpAmount: changesSavedOk.volpAmount, buyerCode: changesSavedOk.buyerCode, buyerId: changesSavedOk.buyerId, chargeAmount: changesSavedOk.chargeAmount, currencyCode: changesSavedOk.currencyCode, 
        chartererCode: this.ShippmentFormGroup.value['operatorCode'], quantity: changesSavedOk.quantity};
        (this.gridContract.dataSource as object[]).splice(this.gridContract.currentViewData.length, 0, rdata);
        this.isDataChanged = true;
        this.ShippmentFormGroup.patchValue({ changed: true }, { emitEvent: false });
        this.gridContract.refresh();
      }
    }).catch(error => {
      console.log(error);
    });
  }

  endEditCallsGrid(){
    this.ShippmentFormGroup.patchValue({ changed: true }, { emitEvent: false });
    this.gridCalls.endEdit();   
    this.gridCalls.refresh();
  }

  endEditChargesGrid(){
    this.gridCharges.endEdit();
  }

  doubleclickChargeGrid(args){
    this.initialChargeDesc = args.rowData['chargeDesc'];
    this.initialAccountCustomer = args.rowData['accountShipperCode'];
    this.initialCargoType = args.rowData['cargoType'];
    this.initialCurrency = args.rowData['currencyCode'];
    this.initialDebitCredit = args.rowData['debitFlag'];
  }

  addFromToCustomer(args){

    let customerTypeArray = [];

    customerTypeArray.push({customerType: 'BUYER'});
    customerTypeArray.push({customerType: 'SHIPPER'});
    customerTypeArray.push({customerType: 'AGENT'});
    customerTypeArray.push({customerType: 'OWNER'});

    const modalRef = this.modalService.open(BaseDialogComponent, { windowClass: 'modalDialogClass' });
    modalRef.componentInstance.childItem = new DialogChildItem(ShipperChooseFormComponent, customerTypeArray);
    modalRef.result.then(changesSavedOk => {
      if (changesSavedOk) {
        var formEle = document.getElementById("gridCharges").querySelector("form").ej2_instances[0];
        var invoiceReceiver = formEle.getInputElement('invoiceReceiver');
        invoiceReceiver.value = changesSavedOk[0].code;
        var customerReceiver = formEle.getInputElement("input");
        customerReceiver.value = changesSavedOk[0].name;
        this.customerReceiverChanged = true;
        this.customerReceivedChangedSynonim = changesSavedOk[0].name;
        var operatorType = formEle.getInputElement('operatorType');
        operatorType.value = 'SHIPPER';
      }
    }).catch(error => {
      console.log(error);
    });
  }

  deleteContract(){
    let selectedRow: Object = (this.gridContract.getSelectedRecords()[0]);
    const selectedRowIndex: number = this.gridContract.getSelectedRowIndexes()[0];
    let itemId: number = selectedRow['itemId'];
    if(itemId){
      if (this.gridContract.getSelectedRowIndexes().length) {
        let msg = "Please confirm delete operation? \n Proceed with the operation?";
        const modalRef = this.modalService.open(ConfirmDialogComponent);
        modalRef.componentInstance.confirmQuestion = msg;
        modalRef.result.then((result) => {
          if (result == true) {
            (this.gridContract.dataSource as object[]).splice(selectedRowIndex, 1);
            this.gridContract.refresh();
            this.crudService.deleteSingleEntity(itemId, 'contractlist', isAppIdentity.get('jadrolog')).subscribe(() => {
              alert('Item deleted successfully.');
            });
          }
        }).catch((error) => {
          console.log(error);
        });
      } else {
        alert('No selected call for delete operation.');
      }
    }else{
      (this.gridContract.dataSource as object[]).splice(selectedRowIndex, 1);
      this.isDataChanged = true;
      this.gridContract.refresh();
    }
  }

  actionChargesBegin(args: SaveEventArgs) {
    if (args.requestType === 'save') {
      if(this.customerReceiverChanged){
        args.data['customerReceiver']['synonim'] = this.customerReceivedChangedSynonim;
        this.customerReceiverChanged = !this.customerReceiverChanged;
      }
    }
    if(args.requestType === 'beginEdit'){
      if(args.rowData['debitFlag'] === 1){
      }
    }
  }

  actionCallsBegin(args: SaveEventArgs) {
    if (args.requestType === 'save') {
      if(this.portNameChanged){
        args.data['portName'] = this.portNameChangedName;
        this.portNameChanged = !this.portNameChanged;
      }
      this.gridCalls.dataSource[this.selectedCallIndex[0]] = args.data;
      this.gridCalls.refresh();
    }
  }

  chargeListPicker(){

    let paramArray = [];
    paramArray.push({voyageType: this.ShippmentFormGroup.value['charterType'], language: 'US', chargeDropdown: this.chargeObj});

    if(this.ShippmentFormGroup.value['voyageId'] == null){
      window.alert('Invalid voyage or voyage not saved!');
      return;
    }

    if(this.gridCharges.currentViewData.length > 0){
      const modalRef = this.modalService.open(ConfirmDialogComponent);
      modalRef.componentInstance.confirmQuestion = 'Charges already exist. Existing data will be overwritten. \r\n Proceed with the operation?';
      modalRef.result.then((result) => {
        if (result == true) {
          for(let i = 0; i < this.gridCharges.currentViewData.length; i++){
            this.crudService.deleteSingleEntity(Number(this.gridCharges.currentViewData[i]['itemId']), 'chargelist', isAppIdentity.get('jadrolog')).subscribe(() => {
            });
          }
          (this.gridCharges.dataSource as object[]).splice(0, this.gridCharges.currentViewData.length);
          this.gridCharges.refresh();
          const modalRef = this.modalService.open(BaseDialogComponent, { windowClass: 'modalDialogClass' });
          modalRef.componentInstance.childItem = new DialogChildItem(ChargeListPickerComponent, paramArray);
          modalRef.result.then(changesSavedOk => {
            if (changesSavedOk) {
              for(let i = 0; i < changesSavedOk.length; i++){
                let newCustomerAccount: CustomerShipperChargeModel = new CustomerShipperChargeModel();
                let newFromTo: CustomerShipperChargeModel = new CustomerShipperChargeModel();
                let amountDebit: number = null, amountCredit: number = null, debitFlag: number = null, itemStatus: number = null;
                let currencyCode: string = '';
                if(changesSavedOk[i]['defDebit'] == 1){
                  amountDebit = 0;
                  amountCredit = null;
                  debitFlag = 1;
                }
                if(changesSavedOk[i]['defCredit'] == 1 && (changesSavedOk[i]['defDebit'] == 0 || changesSavedOk[i]['defDebit'] == null)){
                  amountDebit = null;
                  amountCredit = 0;
                  debitFlag = 0;
                }
                if(changesSavedOk[i]['defConfirmed'] == 1){
                  itemStatus = 1;
                }else{
                  itemStatus = 0;
                }
                currencyCode = changesSavedOk[i]['defCurrency'];
                const rdata: object = { chargeCode: changesSavedOk[i].chargeCode, chargeDesc: changesSavedOk[i].charges.names.name, shpView: 1, tcView: 1, invoiceAmountDebit: amountDebit, 
                commisionRate: 0, commisionAmount: 0, accountShipperCode: 'JADROLOG', accountCode: 'JADROLOG', voyageId: this.ShippmentFormGroup.value['voyageId'], operatorCode: 'JADROLOG', 
                itemOrder: i + 1, invoiceAmountCredit: amountCredit, invoiceReceiver: 'JADROLOG', customer: newCustomerAccount, customerReceiver: newFromTo, currencyCode: currencyCode, debitFlag: debitFlag, 
                itemStatus: itemStatus};
                (this.gridCharges.dataSource as object[]).splice(0, 0, rdata);
                this.gridCharges.refresh();
              }
            }
            }).catch(error => {
              console.log(error);
            });
        }else{
          this.output.emit(null);
        }
      }).catch((error) => {
        console.log(error);
      });
    }else{
      const modalRef = this.modalService.open(BaseDialogComponent, { windowClass: 'modalDialogClass' });
          modalRef.componentInstance.childItem = new DialogChildItem(ChargeListPickerComponent, paramArray);
          modalRef.result.then(changesSavedOk => {
            if (changesSavedOk) {
              for(let i = 0; i < changesSavedOk.length; i++){
                let newCustomerAccount: CustomerShipperChargeModel = new CustomerShipperChargeModel();
                let newFromTo: CustomerShipperChargeModel = new CustomerShipperChargeModel();
                let amountDebit: number = null, amountCredit: number = null, debitFlag: number = null, itemStatus: number = null;
                let currencyCode: string = '';
                if(changesSavedOk[i]['defDebit'] == 1){
                  amountDebit = 0;
                  amountCredit = null;
                  debitFlag = 1;
                }
                if(changesSavedOk[i]['defCredit'] == 1 && (changesSavedOk[i]['defDebit'] == 0 || changesSavedOk[i]['defDebit'] == null)){
                  amountDebit = null;
                  amountCredit = 0;
                  debitFlag = 0;
                }
                if(changesSavedOk[i]['defConfirmed'] == 1){
                  itemStatus = 1;
                }else{
                  itemStatus = 0;
                }
                currencyCode = changesSavedOk[i]['defCurrency'];
                const rdata: object = { chargeCode: changesSavedOk[i].chargeCode, chargeDesc: changesSavedOk[i].charges.names.name, shpView: 1, tcView: 1, invoiceAmountDebit: amountDebit, 
                commisionRate: 0, commisionAmount: 0, accountShipperCode: 'JADROLOG', accountCode: 'JADROLOG', voyageId: this.ShippmentFormGroup.value['voyageId'], operatorCode: 'JADROLOG', 
                itemOrder: i + 1, invoiceAmountCredit: amountCredit, invoiceReceiver: 'JADROLOG', customer: newCustomerAccount, customerReceiver: newFromTo, currencyCode: currencyCode, debitFlag: debitFlag, 
                itemStatus: itemStatus};
                (this.gridCharges.dataSource as object[]).splice(0, 0, rdata);
                this.gridCharges.refresh();
              }
            }
            }).catch(error => {
              console.log(error);
            });
    }
  }

  changeCallStatusPicker(callStatus: String){
    let ShippmentModel = (this.ShippmentFormGroup as FormGroup).getRawValue() as VoyageOverviewModel;
    let voyageCalls: VoyageCallsModel;

    if(callStatus == 'FINAL'){
      let isPreliminaryChanged = false;
      let currentPreliminary = this.gridCalls.getCurrentViewRecords();
      if(currentPreliminary.length != this.callsArrayPreliminary.length){
        isPreliminaryChanged = true;
      }else{
        for(let i = 0; i < currentPreliminary.length; i++){
          if(currentPreliminary[i] != this.callsArrayPreliminary[i]){
            isPreliminaryChanged = true;
          }
        }
      }

      if(isPreliminaryChanged){
        const modalRef = this.modalService.open(ConfirmDialogComponent);
        modalRef.componentInstance.confirmQuestion = 'Preliminary calls are changed. You need to save the changes first. Do you want to save changes?';
        modalRef.result.then((result) => {
          if (result == true) {
            this.crudService.doActionOfPostType(ShippmentModel.voyageId, 'callslist', null, currentPreliminary, isAppIdentity.get('jadrolog'))
              .subscribe(data => {
                this.crudService.retrieveEntityListById(voyageCalls, this.input[0].voyageId, 'voyagecalls', isAppIdentity.get('jadrolog')).subscribe(data => {
                  this.callsArrayPreliminary = data.filter( p => p.itemStatus == 'PRELIMINARY');
                });
            });
          }
        });
      }
      this.callsArray = this.callsArrayFinal;
      for (const cols of this.gridCalls.columns) {
        if ((cols as any).field === 'nextPortDistance') {
            (cols as any).width = '10';
        }
        if ((cols as any).field === 'vesselSpeed') {
          (cols as any).width = '10';
        }
        if ((cols as any).field === 'navigationDays') {
          (cols as any).width = '10';
        }
      }
    }else{
      let isFinalChanged = false;
      let currentFinal = this.gridCalls.getCurrentViewRecords();
      if(currentFinal.length != this.callsArrayFinal.length){
        isFinalChanged = true;
      }else{
        for(let i = 0; i < currentFinal.length; i++){
          if(currentFinal[i] != this.callsArrayFinal[i]){
            isFinalChanged = true;
          }
        }
      }

      if(isFinalChanged){
        const modalRef = this.modalService.open(ConfirmDialogComponent);
        modalRef.componentInstance.confirmQuestion = 'Final calls are changed. You need to save the changes first. Do you want to save changes?';
        modalRef.result.then((result) => {
          if (result == true) {
            this.crudService.doActionOfPostType(ShippmentModel.voyageId, 'callslist', null, currentFinal, isAppIdentity.get('jadrolog'))
              .subscribe(data => {
                this.crudService.retrieveEntityListById(voyageCalls, this.input[0].voyageId, 'voyagecalls', isAppIdentity.get('jadrolog')).subscribe(data => {
                  this.callsArrayFinal = data.filter( p => p.itemStatus == 'FINAL');
                });
            });
          }
        });
      }
      this.callsArray = this.callsArrayPreliminary;
      for (const cols of this.gridCalls.columns) {
        if ((cols as any).field === 'nextPortDistance') {
            (cols as any).width = '0';
        }
        if ((cols as any).field === 'vesselSpeed') {
          (cols as any).width = '0';
        }
        if ((cols as any).field === 'navigationDays') {
          (cols as any).width = '0';
        }
      }
    }
    this.gridCalls.refresh();
  }

  confirmCalls(){
    let ShippmentModel = (this.ShippmentFormGroup as FormGroup).getRawValue() as VoyageOverviewModel;
    let voyageCalls: VoyageCallsModel;

    let newFinalCalls = [];
    if(this.callsArrayFinal.length > 0){
      alert('Final calls already exist.');
      return;
    }else{
      newFinalCalls = this.callsArrayPreliminary;
      for(let i = 0; i < newFinalCalls.length; i++){
        newFinalCalls[i]['itemStatus'] = 'FINAL';
        newFinalCalls[i]['portCallOrder'] = newFinalCalls[i]['portCallOrder'] + 1;
        newFinalCalls[i]['callId'] = null;
      }
      const balastCall: object = { operationCode: 'Balast', portName: '', portDays: 0, eta: null, etd: new Date(), voyageId: this.input[0].voyageId, loadCountry: 'XX', loadPort: 'XXX', destCountry: 'XX', destPort: 'XXX', itemStatus:'FINAL', portCallOrder: 1};
      (newFinalCalls as object[]).splice(0, 0, balastCall);

      if((newFinalCalls as object[]).length > 0){
        this.crudService.doActionOfPostType(ShippmentModel.voyageId, 'callslist', null, newFinalCalls, isAppIdentity.get('jadrolog'))
          .subscribe(data => {
            alert('Final calls added successfully.');
            this.crudService.retrieveEntityListById(voyageCalls, this.input[0].voyageId, 'voyagecalls', isAppIdentity.get('jadrolog')).subscribe(data => {
              this.callsArrayPreliminary = data.filter( p => p.itemStatus == 'PRELIMINARY');
              this.callsArrayFinal = data.filter( p => p.itemStatus == 'FINAL');
              this.callsArray = this.callsArrayPreliminary;
            });
        });
      }
    }
  }

  getNavigationDays(etd: Date, eta: Date){
    return (eta.getTime() - etd.getTime())/1000/60/60/24;
  }

  changeChargeCheckbox(args: any){
    let rowIndex: any = args.target.closest('td').getAttribute("index");  
    let checkedState: number;

    if(args.target.checked){
      checkedState = 1;
      this.indexArray.push(rowIndex);
    }else{
      checkedState = 0;
      this.indexArray.splice(this.indexArray.indexOf(rowIndex),1);
    }
    
    switch(args.target.id){
      case ('itemOperationCheckbox'):{
        this.gridCharges.currentViewData[Number(rowIndex)]['itemOperation'] = checkedState;
        break;
      }
    }
    this.gridCharges.dataSource = this.gridCharges.currentViewData;
    this.gridCharges.refresh();
  }

  dataChanged(){
    this.isDataChanged = true;
  }
}

